﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SportsPlatform.Base;
using SportsPlatform.Dto.WeChat;
using SportsPlatform.Query.WeChat;
using SportsPlatform.WeChat.IWeChat;
using SportsPlatform.Model.SportBusiness;
using SportsPlatform.Consts;
using Abp.Domain.Repositories;
using Abp.Collections.Extensions;
using Abp.Application.Services;
using SportsPlatform.Enums;
using SportsPlatform.Helpers;
using static iTextSharp.text.pdf.AcroFields;
using SportsPlatform.Dto.SportBusiness.Information;
using Microsoft.AspNetCore.Http;
using Org.BouncyCastle.Asn1.X9;
using Senparc.Weixin.MP.AdvancedAPIs;
using System.Collections.Immutable;
using Polly.Caching;
using SportsPlatform.SqlExecuter;

namespace SportsPlatform.WeChat.WeChat
{
    /// <summary>
    /// 移动端我的报名接口实现
    /// </summary>
    [RemoteService(false)]
    public class RegistrationService : SportsPlatformAppServiceBase, IRegistrationService
    {
        //报名信息
        private readonly IRepository<RegistrationInfo, Guid> _registrationInfoRepository;
        //赛事信息
        private readonly IRepository<Competition, Guid> _competitionRepository;
        //赛事项目信息
        private readonly IRepository<CompetitionProject, Guid> _competitionProjectRepository;
        //支付订单信息
        private readonly IRepository<PaymentOrderInfo, Guid> _paymentOrderInfoRepository;

        private readonly IRepository<PaymentOrderOperationInfo, Guid> _paymentOrderOperationRepository;
        /// <summary>
        /// 用户仓储
        /// </summary>
        private readonly IRepository<Employee, Guid> _employeeRepository;
        /// <summary>
        /// 赛事团队仓储
        /// </summary>
        private readonly IRepository<CompeteTeam, Guid> _comteamRepository;

        private readonly ISqlExecuterRepository _sqlExecuterRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        public RegistrationService(IRepository<RegistrationInfo, Guid> registrationInfoRepository, IRepository<Competition, Guid> competitionRepository,
            IRepository<CompetitionProject, Guid> competitionProjectRepository, IRepository<PaymentOrderInfo, Guid> paymentOrderInfoRepository,
            IRepository<Employee, Guid> employeeRepository, IRepository<CompeteTeam, Guid> comteamRepository, ISqlExecuterRepository sqlExecuterRepository,
            IRepository<PaymentOrderOperationInfo, Guid> paymentOrderOperationRepository,
            IHttpContextAccessor context) : base(context)
        {
            _registrationInfoRepository = registrationInfoRepository;
            _competitionRepository = competitionRepository;
            _competitionProjectRepository = competitionProjectRepository;
            _paymentOrderInfoRepository = paymentOrderInfoRepository;
            _employeeRepository = employeeRepository;
            _comteamRepository = comteamRepository;
            _paymentOrderOperationRepository = paymentOrderOperationRepository;
            _sqlExecuterRepository= sqlExecuterRepository;
        }

        /// <summary>
        /// 移动端增加报名信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> AddOrUpdateWeChatRegistration(List<AddWeChatRegistrationQuery> query)
        {
            BaseResultDto dto = new BaseResultDto();
            try
            {
                var project = await _competitionProjectRepository.GetAllListAsync(a => a.CompetitionId == query.First().CompetitionId && a.State > 0 && a.IsDeleted == false);
                var comteamlist = await _comteamRepository.GetAllListAsync(info => info.IsDeleted == false);
                foreach (AddWeChatRegistrationQuery item in query)
                {
                    RegistrationInfo reginfo = ObjectMapper.Map<RegistrationInfo>(item);
                    
                    reginfo.RegistrationSubmissionTime = DateTime.Now;
                    reginfo.CreateTime = DateTime.Now;
                    reginfo.CreateUserId = item.EmployeeId; ;
                    reginfo.RegistrationStatus = (int)RegistrationStatusEnum.待审核;
                    var p = project.First(a => a.Id == item.CompetitionProjectId);
                    if (p.GameType == (int)CompetitionProjectTypeEnum.个人赛)
                    {
                        //获取当前项目的报名数量
                        var reg = (await _registrationInfoRepository.GetAllListAsync(a => a.CompetitionProjectId == item.CompetitionProjectId)).Count;
                        reginfo.SerialNum = reg + 1;
                    }
                    else {
                        //团体赛处理团队Id
                        if (!item.CompeteTeamName.IsNullAndEmpty())
                        {
                            //comteamlist 已经通过赛事项目Id筛选了，这里不用再次用赛事项目筛选
                            var comteaminfo = comteamlist.FirstOrDefault(info => info.Name == item.CompeteTeamName && info.CompetitionProjectId==item.CompetitionProjectId);
                            //为空就新建
                            if (comteaminfo == null)
                            {
                                Guid id = Guid.NewGuid();
                                //这里new是为了防止后面修改遗忘这里引用
                                var comteam = new CompeteTeam()
                                {
                                    Id = id,
                                    Name = item.CompeteTeamName,
                                    CompetitionProjectId = item.CompetitionProjectId,
                                    IsDeleted = false
                                };
                                //efcore事后才执行，会导致之前插入了查询不到
                                string sql = $"insert into T_B_CompeteTeam(Id,Name,CompetitionProjectId,IsDeleted) values('{comteam.Id}','{comteam.Name}','{comteam.CompetitionProjectId}',0)";
                                _sqlExecuterRepository.Execute(sql, null);
                                reginfo.CompeteTeamId = id;
                                //插入之后重新获取
                                comteamlist = await _comteamRepository.GetAllListAsync(info => info.IsDeleted == false && info.CompetitionProjectId == item.CompetitionProjectId);
                            }
                            else
                            {
                                reginfo.CompeteTeamId = comteaminfo.Id;
                            }
                        }
                    }
                    await _registrationInfoRepository.InsertAsync(reginfo);
                }
                dto.IsSuccess = true;
                dto.Code = HttpResultCode.Success;
                dto.Message = "报名成功！";
            }
            catch (Exception ex)
            {
                dto.IsSuccess = false;
                dto.Code = HttpResultCode.Error;
                dto.Message = ex.Message.ToString();
            }
            return dto;
        }

        /// <summary>
        /// 通过时间判断是否与比赛时间冲突
        /// </summary>
        /// <returns></returns>
        public async Task<ResultDto<bool>> GetByTimeIsConflict(List<AddWeChatRegistrationISQuery> querys)
        {
            ResultDto<bool> result = new ResultDto<bool>();
            try
            {
                //弃用，没法判断，比赛时间本来就是一个大的时间段，交叉进行比赛。
                //var ems = await _employeeRepository.GetAllListAsync();
                //var cmps = await _competitionProjectRepository.GetAllListAsync();
                //var regalls = await _registrationInfoRepository.GetAllListAsync();

                //foreach (var item in querys)
                //{
                //    var em = ems.FirstOrDefault(e => e.IDNumber == item.CompeteIdNo);
                //    if (em.IsNullAndEmpty())
                //    {
                //        result.IsSuccess = false;
                //        result.Code = HttpResultCode.Fail;
                //        result.Message = "该身份证号不存在";
                //        return result;
                //    }
                //    //当前参赛用户所选的赛事项目
                //    var cmp = cmps.FirstOrDefault(cmp => cmp.Id == item.CompetitionProjectId);
                //    if (cmp.IsNullAndEmpty())
                //    {
                //        result.IsSuccess = false;
                //        result.Code = HttpResultCode.NotData;
                //        result.Message = "该赛事项目标识不存在";
                //        return result;
                //    }

                //    //查询当前参赛用户当前赛事所有未审核失败的比赛项目
                //    var regs = regalls.Where(r => r.EmployeeId == em.Id && r.CompetitionId == item.CompetitionId && r.RegistrationStatus < 3).ToList();

                //    if (regs.Count > 0)
                //    {
                //        foreach (var registration in regs)
                //        {
                //            var cmpe = cmps.FirstOrDefault(p => p.Id == registration.CompetitionProjectId);

                //            //判断当前比赛项目的日期和之前的比赛项目的日期是否是同一天；是则判断两个项目的比赛时间段是否存在冲突
                //            //冲突判断条件：当前比赛项目的开始时间大于之前比赛项目的结束时间则存在冲突，反之则不冲突
                //            if (Convert.ToDateTime(cmp.GameDate.ToString("yyyy-MM-dd")) == Convert.ToDateTime(cmpe.GameDate.ToString("yyyy-MM-dd")))
                //            {
                //                //两个时间需要拼接之后再去进行判断，因为赛事项目的开始时间用户选择的时候是选择的时分，但是程序在执行保存到数据库的时候，数据库会加上当天的日期之后再保存到数据库中
                //                //所以如果一个赛事中，添加比赛项目的时间不是同一天，那么直接把当前比赛项目的比赛开始时间和之前的比赛项目的比赛时间进行判断的话，会出现判断有误的情况，所以需要把两个时间进行重新拼接一下再进行判断
                //                var begin = Convert.ToDateTime(cmp.GameDate.ToString("yyyy-MM-dd") + " " + cmp.GameBeginTime.ToString("HH:mm"));
                //                var end = Convert.ToDateTime(cmpe.GameDate.ToString("yyyy-MM-dd") + " " + cmpe.GameEndTime.ToString("HH:mm"));
                //                if (begin >= end)
                //                {
                //                    result.IsSuccess = true;
                //                    result.Message = "有冲突";
                //                    result.Code = HttpResultCode.Success;
                //                    result.Data = true;
                //                    return result;
                //                }
                //            }
                //        }
                //    }
                //}
                result.IsSuccess = true;
                result.Message = "无冲突";
                result.Code = HttpResultCode.Success;
                result.Data = false;
                return result;

            }
            catch (Exception e)
            {
                result.IsSuccess = false;
                result.Code = HttpResultCode.Error;
                result.Message = e.Message.ToString();
            }
            return result;
        }

        /// <summary>
        /// 我的报名详情查询
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<ResultDto<RegistrationInfoDetailsDto>> GetRegistrationInfoDetails(RegistrationDetailsQuery query)
        {
            ResultDto<RegistrationInfoDetailsDto> resultDto = new ResultDto<RegistrationInfoDetailsDto>();
            try
            {
                RegistrationInfoDetailsDto dto = new RegistrationInfoDetailsDto();

                //根据订单ID查询当前订单包含的报名信息
                var registrationlist = await _registrationInfoRepository.GetAllListAsync(a => a.PaymentOrderId == query.PaymentOrderId && a.IsDeleted == false);

                if (registrationlist.Count > 0)
                {
                    dto.RegistrationSubmissionTime = registrationlist.FirstOrDefault().RegistrationSubmissionTime.ToString("yyyy.MM.dd  HH:mm:ss");

                    //赛事信息
                    var competition = _competitionRepository.FirstOrDefault(info => info.Id == query.CompetitionId);
                    var projectlist = await _competitionProjectRepository.GetAllListAsync(a => a.CompetitionId == query.CompetitionId);
                    if (competition != null)
                    {
                        dto.CompetitionName = competition.Name;
                        dto.CoverPicture = competition.CoverPicture;
                        dto.CompetitionMatchTime = competition.MatchBeginTime.ToString("yyyy.MM.dd") + "-" + competition.MatchEndTime.ToString("MM.dd");
                        dto.CompetitionAddress = competition.City;
                    }
                    else
                    {
                        dto.CompetitionName = "";
                        dto.CoverPicture = "";
                        dto.CompetitionMatchTime = "";
                        dto.CompetitionAddress = "";
                    }
                    var order = _paymentOrderInfoRepository.FirstOrDefault(info => info.Id == query.PaymentOrderId);
                    dto.OrderOddNumbers = String.IsNullOrEmpty(dto.OrderOddNumbers) ? order.OrderOddNumbers : dto.OrderOddNumbers + "、" + order.OrderOddNumbers;
                    dto.PaymentTime = order.PaymentTime != null ? ((DateTime)order.PaymentTime).ToString("yyyy.MM.dd  HH:mm:ss") : null;
                    dto.CompetitionPayStates = Enum.GetName(typeof(PaymentStatusEnum), order.PaymentStatus);

                    //项目信息
                    List<CompetitionProjectDto> competitionProjectDtos = new List<CompetitionProjectDto>();

                    var prolilst = registrationlist.GroupBy(a => new { a.CompetitionProjectId }).Select(a => new { Id = a.Key.CompetitionProjectId }).ToList();
                    foreach (var item in prolilst)
                    {
                        CompetitionProjectDto competitionProjectDto = new CompetitionProjectDto();

                        var reglist = registrationlist.Where(a => a.CompetitionProjectId == item.Id).ToList();
                        var project = projectlist.Where(a => a.Id == item.Id).First();
                        competitionProjectDto.CompetitionProjectName = project.Name;
                        var gameendtime = project.GameBeginTime.Date == project.GameEndTime.Date ? project.GameEndTime.ToString("HH:mm") : project.GameEndTime.ToString("yyyy.MM.dd HH:mm");
                        competitionProjectDto.GameTime = $"{project.GameBeginTime.ToString("yyyy.MM.dd HH:mm")}-{gameendtime}";
                        competitionProjectDto.CostMoney = (decimal)(project.CostMoney != null ? project.CostMoney : decimal.Parse("0"));
                        competitionProjectDto.CostType = project.CostType == 1 ? "/人" : "/队";
                        competitionProjectDto.GameTypeName = Enum.GetName(typeof(CompetitionProjectTypeEnum), project.GameType);
                        if (project.CostType == 1)
                        {
                            competitionProjectDto.CompeteNumber = reglist.Count.ToString() + "人";
                            competitionProjectDto.CountMoney = (decimal)(project.CostMoney != null ? project.CostMoney : decimal.Parse("0")) * reglist.Count;
                        }
                        else
                        {
                            competitionProjectDto.CompeteNumber = "1队";
                            competitionProjectDto.CountMoney = (decimal)(project.CostMoney != null ? project.CostMoney : decimal.Parse("0"));
                        }

                        List<CompeteInfo> CompeteInfoList = new List<CompeteInfo>();
                        reglist.ForEach(compete =>
                        {
                            CompeteInfo competeInfo = new CompeteInfo();

                            //查询当前用户的报名信息是否退款
                            var pay = (_paymentOrderOperationRepository.GetAllList(a => a.RegistrationID == compete.Id && a.PaymentState == (int)PaymentStatusEnum.已退款)).FirstOrDefault();
                            if (pay != null)
                            {
                                competeInfo.PayStates = "已退款";
                            }

                            competeInfo.Name = compete.CompeteName;
                            competeInfo.SensorNumber = compete.SensorNumber;
                            competeInfo.IdNo = compete.CompeteIdNo;
                            competeInfo.Phone = compete.CompeteTel;
                            CompeteInfoList.Add(competeInfo);
                        });
                        competitionProjectDto.CompeteTeamName = reglist.First().CompeteTeamName;
                        competitionProjectDto.CompeteInfoList = CompeteInfoList;
                        competitionProjectDtos.Add(competitionProjectDto);
                    }

                    dto.CompetitionProjectList = competitionProjectDtos;
                    resultDto.IsSuccess = true;
                    resultDto.Code = HttpResultCode.Success;
                    resultDto.Data = dto;
                }
                else
                {
                    resultDto.IsSuccess = false;
                    resultDto.Code = HttpResultCode.SqlError;
                    resultDto.Message = "未查询到相关信息！";
                }

            }
            catch (Exception e)
            {
                resultDto.IsSuccess = false;
                resultDto.Code = HttpResultCode.Error;
                resultDto.Message = e.Message.ToString();
            }
            return resultDto;
        }

        /// <summary>
        /// 分页查询我的报名信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<PagePagingDto<RegistrationInfoPageDto>> GetRegistrationInfoPage(RegistrationInfoListQuery query)
        {
            PagePagingDto<RegistrationInfoPageDto> pagePagingDto = new PagePagingDto<RegistrationInfoPageDto>();
            try
            {
                List<RegistrationInfoPageDto> registrationInfoPageDtos = new List<RegistrationInfoPageDto>();
                //获取当前人员的订单列表
                var orderlist = await _paymentOrderInfoRepository.GetAllListAsync(a => a.EmployeeID == query.EmployeeId && a.IsDeleted == false);
                int ordercount = orderlist.Count;
                orderlist = orderlist.OrderByDescending(a => a.CreateTime).Skip((query.PageIndex - 1) * query.PageSize).Take(query.PageSize).ToList();
                //获取赛事比赛项目
                var projectlist = await _competitionProjectRepository.GetAllListAsync(a => a.IsDeleted == false && a.State > 0);
                //获取当前人员的报名信息列表
                var registrationlist = await _registrationInfoRepository.GetAllListAsync(info => info.EmployeeId == query.EmployeeId && info.IsDeleted == false);

                var competition = await _competitionRepository.GetAllListAsync(a => a.IsDeleted == false);

                if (orderlist != null && orderlist.Count() > 0)
                {
                    foreach (var item in orderlist)
                    {
                        RegistrationInfoPageDto dto = new RegistrationInfoPageDto();
                        var com = competition.Where(a => a.Id == item.CompetitionID).FirstOrDefault();
                        dto.CompetitionId = item.CompetitionID;
                        dto.CompetitionName = com.IsNullAndEmpty() ? "" : com.Name;
                        dto.CompetitionAddress = com.IsNullAndEmpty() ? "" : com.City + "|" + com.Address;
                        dto.CompetitionMatchTime = com.IsNullAndEmpty() ? "" : com.MatchBeginTime.ToString("yyyy.MM.dd") + "-" + com.MatchEndTime.ToString("MM.dd");

                        //合并赛事项目名称
                        string competitionProjectName = "";
                        var plist = registrationlist.Where(a => a.PaymentOrderId == item.Id).ToList();
                        if (plist.Count > 0)
                        {
                            plist.ForEach(p =>
                            {
                                var project = projectlist.FirstOrDefault(a => a.Id == p.CompetitionProjectId);
                                if (project != null)
                                {
                                    competitionProjectName += project.Name + "、";
                                }
                            });
                            if (!string.IsNullOrEmpty(competitionProjectName))
                            {
                                dto.CompetitionProjectName = competitionProjectName.Substring(0, competitionProjectName.Length - 1);
                            }
                            else
                            {
                                dto.CompetitionProjectName = "";
                            }
                            dto.RegistrationSubmissionTime = plist.First().RegistrationSubmissionTime.ToString("yyyy.MM.dd  HH:mm:ss");
                        }
                        dto.Id = item.Id;
                        dto.CompetitionPayStates = Enum.GetName(typeof(PaymentStatusEnum), item.PaymentStatus);
                        registrationInfoPageDtos.Add(dto);
                    }

                    pagePagingDto.IsSuccess = true;
                    pagePagingDto.Code = HttpResultCode.Success;
                    pagePagingDto.Data = registrationInfoPageDtos;
                    pagePagingDto.TotalCount = ordercount;
                }
                else
                {
                    pagePagingDto.IsSuccess = false;
                    pagePagingDto.Code = HttpResultCode.SqlError;
                    pagePagingDto.Message = "未查询到相关信息！";
                }
            }
            catch (Exception e)
            {
                pagePagingDto.IsSuccess = false;
                pagePagingDto.Code = HttpResultCode.Error;
                pagePagingDto.Message = e.Message.ToString();
            }
            return pagePagingDto;
        }
    }
}
